package com.wwdx.shiro;

import org.apache.shiro.cache.AbstractCacheManager;
import org.apache.shiro.cache.Cache;
import org.apache.shiro.cache.CacheException;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.RedisTemplate;

import java.util.Collection;
import java.util.Set;

/**
 * redis的缓存管理器
 * @author liguoliang
 * @date 2018-1-23
 */
public class ShiroRedisCacheManager extends AbstractCacheManager {

    private RedisTemplate redisTemplate;

    public void setRedisTemplate(RedisTemplate redisTemplate) {
        this.redisTemplate = redisTemplate;
    }

    @Override
	protected Cache createCache(String cacheName) throws CacheException {
		return new ShiroRedisCache<String, Object>(cacheName);
	}

	class ShiroRedisCache<K, V> implements Cache<K, V> {

        HashOperations hashOperations = redisTemplate.opsForHash();
		private String name;

		ShiroRedisCache(String name) {
            if (name == null) {
                throw new IllegalArgumentException("Cache name cannot be null.");
            }else {
                this.name = name;
            }
		}

		@Override
		public V get(K key) throws CacheException {
			return (V) hashOperations.get(name, key);
		}

		@Override
		public V put(K key, V value) throws CacheException {
			hashOperations.put(name, key, value);
			return value;
		}

		@Override
		public V remove(K key) throws CacheException {
			hashOperations.delete(name, key);
			return this.get(key);
		}

		@Override
		public void clear() throws CacheException {
			redisTemplate.delete(name);
		}

		@Override
		public int size() {
			return hashOperations.size(name).intValue();
		}

		@Override
		public Set<K> keys() {
			return hashOperations.keys(name);
		}

		@Override
		public Collection<V> values() {
			return hashOperations.values(name);
		}
	}
}